package com.jstyle.jclife.activity;

import android.Manifest;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.drawable.AnimationDrawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.provider.Settings;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AlertDialog;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.jstyle.blesdk.Util.ResolveUtil;
import com.jstyle.blesdk.cmdenum.SendCmdState;
import com.jstyle.blesdk.constant.DeviceKey;
import com.jstyle.jclife.BuildConfig;

import com.jstyle.jclife.NetWork.NetWorkUtil;
import com.jstyle.jclife.R;
import com.jstyle.jclife.app.MyApplication;
import com.jstyle.jclife.ble.BleManager;
import com.jstyle.jclife.ble.BleService;
import com.jstyle.jclife.daoManager.BindDeviceInfoDaoManager;
import com.jstyle.jclife.daoManager.UserInfoDaoManager;
import com.jstyle.jclife.fragment.DeviceFragment;
import com.jstyle.jclife.fragment.DeviceNotFindFragment;
import com.jstyle.jclife.model.BindDeviceInfo;
import com.jstyle.jclife.model.BleData;

import com.jstyle.jclife.model.JstyleDevice;
import com.jstyle.jclife.model.NetResultData;
import com.jstyle.jclife.model.UserInfo;
import com.jstyle.jclife.utils.NetWorkConast;
import com.jstyle.jclife.utils.ResolveData;
import com.jstyle.jclife.utils.RxBus;
import com.jstyle.jclife.utils.SchedulersTransformer;
import com.jstyle.jclife.utils.ScreenUtils;
import com.jstyle.jclife.utils.SharedPreferenceUtils;
import com.tbruyelle.rxpermissions2.Permission;
import com.tbruyelle.rxpermissions2.RxPermissions;

import java.util.List;
import java.util.Map;

import butterknife.BindArray;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;

/**
 * 绑定设备
 */
public class BindDeviceActivity extends BaseActivity implements DeviceFragment.OnFragmentInteractionListener ,DeviceNotFindFragment.OnFragmentInteractionListener{

    private static final String TAG = "BindViewDeviceActivity";

    Button btBindViewDeviceFinish;
    @BindView(R.id.bind_device)
    ImageView BindViewDevice;
    boolean isFirst;


    @BindView(R.id.bt_bind_device)
    Button btBindDevice;
    @BindView(R.id.tv_makesure)
    TextView tvMakesure;
    @BindView(R.id.tv_bind_tips)
    TextView tvBindTips;
    @BindView(R.id.tv_search)
    TextView tvSearch;
    @BindView(R.id.bt_skip)
    Button btSkip;
    @BindView(R.id.bt_device_title)
    Button btDeviceTitle;
    @BindView(R.id.iv_back)
    ImageView ivBack;
    @BindView(R.id.rl_title)
    RelativeLayout rlTitle;

    @BindView(R.id.iv_logo)
    ImageView ivLogo;


    private BluetoothAdapter mBluetoothAdapter;
    private static final int REQUEST_ENABLE_BT = 974;
    private Disposable subscription;
    private String deviceAddress;
    private boolean isScanning;
    private Handler mHandler = new Handler();
    JstyleDevice jstyleDevice;
    public static final String BindFinishAction = "BindFinishAction";
    public static final String DeviceRefreshAction = "DeviceRefreshAction";
    private List<BindDeviceInfo> bindDeviceInfoList;
    @BindArray(R.array.fliter_name)
    String[]filteName;
    private AnimationDrawable animationDrawable;
    boolean fromLogin;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_bind_device);
        ButterKnife.bind(this);

        initData();
    }


    private void requestPermissions() {
        RxPermissions rxPermission = new RxPermissions(this);
        rxPermission.requestEachCombined(Manifest.permission.ACCESS_FINE_LOCATION,
                Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.BLUETOOTH, Manifest.permission.BLUETOOTH_ADMIN)
                .subscribe(new Consumer<Permission>() {
                    @Override
                    public void accept(Permission permission) throws Exception {
                        if (permission.granted) {
                            // 用户已经同意该权限
                            startScan(true);
                            displayView(true);
                        } else if (permission.shouldShowRequestPermissionRationale) {
                            // 用户拒绝了该权限，没有选中『不再询问』（Never ask again）,那么下次再次启动时，还会提示请求权限的对话框
                            showNeedPermission();
                            Log.d(TAG, permission.name + " is denied. More info should be provided.");
                        } else {
                            // 用户拒绝了该权限，并且选中『不再询问』
                            showToEnable();
                        }
                    }
                });
    }

    private void showNeedPermission() {
        AlertDialog alertDialog = new AlertDialog.Builder(this, R.style.appalertdialog)
                .setCancelable(false)
                .setTitle(getString(R.string.permission_requierd))
                .setMessage(String.format(getString(R.string.permisson_neverask), "Gps"))
                .setPositiveButton(getString(R.string.require_now), new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        requestPermissions();
                    }
                }).setNegativeButton(getString(R.string.require_cancel), new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {

                    }
                }).create();
        alertDialog.show();
    }

    private void showToEnable() {
        AlertDialog alertDialog = new AlertDialog.Builder(this, R.style.appalertdialog)
                .setCancelable(false)
                .setTitle(R.string.Enable_Access_title)
                .setMessage(R.string.access_content)
                .setPositiveButton(R.string.access_now, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                        Uri uri = Uri.fromParts("package", getApplicationContext().getPackageName(), null);
                        intent.setData(uri);
                        startActivity(intent);
                    }
                }).setNegativeButton(R.string.access_no, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {

                    }
                }).create();
        alertDialog.show();
    }

    private void unsubscribe() {
        if (subscription != null && !subscription.isDisposed()) {
            subscription.dispose();
        }
    }

    private void initData() {
        fromLogin=getIntent().getBooleanExtra(SharedPreferenceUtils.KEY_From_Login,false);
        ivLogo.setVisibility(BuildConfig.APPLICATION_ID.equals("com.jstyle.fomofit") ? View.VISIBLE : View.GONE);
        subscription = RxBus.getInstance().toObservable(BleData.class).observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer<BleData>() {
            @Override
            public void accept(BleData bleData) throws Exception {
                String action = bleData.getAction();
                if (BleService.ACTION_GATT_onDescriptorWrite.equals(action)) {
                    showToast(getString(R.string.connected_success));
                    btBindDevice.setVisibility(View.GONE);
                    tvMakesure.setVisibility(View.INVISIBLE);
                    tvBindTips.setVisibility(View.INVISIBLE);
                    tvSearch.setVisibility(View.GONE);
                    disMissProgressDialog();
                  //  checkBindState();
                    if (isFirst||fromLogin) {
                        SharedPreferenceUtils.setSpBoolean(SharedPreferenceUtils.KEY_Is_First, false);
                        String account = NetWorkUtil.getUserId();
                        UserInfo userInfo = UserInfoDaoManager.getUserByUid(account);
                        Class next=null;
                        if(userInfo==null){
                            next=UserInfoSettingActivity.class;
                        }else{
                            String iconPath=userInfo.getIconPath();
                            next=TextUtils.isEmpty(iconPath) ? UserInfoSettingActivity.class : MainActivity.class;
                            //next=UserInfoSettingActivity.class ;
                        }
                        startActivity(next);
                    }
                    //showBindStatus();
                    sendBindFinishAction();
                    finish();
                } else if (BleService.ACTION_GATT_DISCONNECTED.equals(action)) {
                    showToast(getString(R.string.disonnected));
                    disMissProgressDialog();
                    displayView(false);
                    //showDeviceTypeList();
                }
            }

        });
        ScreenUtils.setTitleTypeface(btDeviceTitle);

        // deviceAddress=SharedPreferenceUtils.getSpString(this,SharedPreferenceUtils.KEY_ADDRESS);
      //  showBindStatus();
        final BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
        mBluetoothAdapter = bluetoothManager.getAdapter();
        if (mBluetoothAdapter == null) {
            finish();
            return;
        }
        isFirst = SharedPreferenceUtils.getBoolean(SharedPreferenceUtils.KEY_Is_First, true);
        startSerchDevice();
    }


    private void sendBindFinishAction() {
        RxBus rxBus = RxBus.getInstance();
        BleData actionData = new BleData();
        actionData.setAction(BindFinishAction);
        rxBus.post(actionData);
    }



    @OnClick({R.id.bt_skip, R.id.bt_bind_device, R.id.iv_back, R.id.bind_device})
    public void onClick(View view) {
        switch (view.getId()) {

            case R.id.bt_skip:
                if (isFirst) {
                    SharedPreferenceUtils.setSpBoolean(SharedPreferenceUtils.KEY_Is_First, false);
                    startActivity(UserInfoSettingActivity.class);
                }
                finish();
                break;
            case R.id.iv_back:
                finish();
                break;
            case R.id.bt_bind_device:
                startSerchDevice();
                break;
        }
    }

    private void startSerchDevice() {
        if(!NetWorkUtil.isNetworkConnected(this)){
            showToast(getString(R.string.network_bad));
            return;
        }
        if (!mBluetoothAdapter.isEnabled()) {
            enableBluetooth();
            return;
        }
        requestPermissions();

    }

    private void displayView(boolean enable) {
        if (enable) {
            BindViewDevice.setImageResource(R.drawable.anim_binddevice);
            animationDrawable = (AnimationDrawable) BindViewDevice.getDrawable();
            animationDrawable.start();
        }else{
            if(animationDrawable!=null) animationDrawable.stop();
            BindViewDevice.setImageResource(R.drawable.scan_device3);
        }
     //   BindViewDevice.setVisibility(enable ? View.VISIBLE : View.INVISIBLE);
        btBindDevice.setVisibility(enable ? View.INVISIBLE : View.VISIBLE);
        tvMakesure.setVisibility(enable ? View.VISIBLE : View.INVISIBLE);
        tvBindTips.setVisibility(enable ? View.VISIBLE : View.INVISIBLE);
        tvSearch.setVisibility(enable ? View.VISIBLE : View.GONE);

    }




    DeviceFragment fragment;

    private void showDeviceDialog() {
        DeviceFragment fragment = new DeviceFragment();
        fragment.show(getSupportFragmentManager(), "device");
    }

    private void enableBluetooth() {
        if (!mBluetoothAdapter.isEnabled()) {
            Intent enableBtIntent = new Intent(
                    BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
        }
    }

    @Override
    public void onFragmentInteraction(String address) {
        Log.i(TAG, "onFragmentInteraction: " + address);
        startScan(false);
        List<BindDeviceInfo>bindDeviceInfoList=BindDeviceInfoDaoManager.queryAllData();
        if(bindDeviceInfoList.size()==1){
            BleManager.getInstance().connectDevice(address);
            showProgressDialog(getString(R.string.connectting));
        }else{
            SharedPreferenceUtils.setSpString(SharedPreferenceUtils.KEY_ADDRESS,address);
            broadcastUpdate(BindDeviceListActivity.ActionDeviceChange,address);
            if(BleManager.getInstance().isConnected()){
                BleManager.getInstance().disconnectDevice();
            }else{
                BleManager.getInstance().connectDevice(address,true);
            }
            if (fromLogin) {
                BleManager.getInstance().connectDevice(address);
                showProgressDialog(getString(R.string.connectting));
            }else {
                finish();
            }
        }

    }
    private void broadcastUpdate(String action,String address) {
        BleData bleData = new BleData();
        bleData.setAction(action);
        bleData.setData(address);
        RxBus.getInstance().post(bleData);
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.i(TAG, "onDestroy: ");
        unsubscribe();
        if (isScanning) startScan(false);
        //   mHandler.removeCallbacksAndMessages(null);
    }

    DeviceFragment deviceFragment;
    private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
        @Override
        public void onLeScan(final BluetoothDevice device, final int rssi, final byte[] scanRecord) {

            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    String name = ResolveData.decodeDeviceName(scanRecord);
                    if (TextUtils.isEmpty(name)) {
                        name = "Unkown Device";
                    }

                    if(isBind(device.getAddress()))return;
                    if (isContain(name) || name.toLowerCase().contains("dfu")) {
                        String seriNumber= ResolveData.parseData(scanRecord);
                        if (deviceFragment == null) {
                            deviceFragment = DeviceFragment.newInstance(device, rssi, name,seriNumber);
                            FragmentTransaction mFragmentTransaction = getSupportFragmentManager().beginTransaction();
                            mFragmentTransaction.add(deviceFragment, "device");
                            mFragmentTransaction.commitAllowingStateLoss();
                        }
                        deviceFragment.addDevice(device, rssi, name,seriNumber);
                    }

                }
            });

        }
    };

    private boolean isContain(String name){
        boolean isConatain=false;
        for(String filter:filteName){
            if(name.toLowerCase().contains(filter)){
                isConatain=true;
                break;
            }
        }
        return isConatain;
    }
    private boolean isBind(String address){
        boolean isBind=false;
        for(BindDeviceInfo bindDeviceInfo:bindDeviceInfoList){
            if(bindDeviceInfo.getMacAddress().equals(address)){
                isBind=true;
                break;
            }
        }
        return isBind;
    }

    private void startScan(boolean enable) {
        // TODO Auto-generated method stub

        if (enable) {
           bindDeviceInfoList=BindDeviceInfoDaoManager.queryAllData();
            deviceFragment = null;
            mHandler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    mBluetoothAdapter.stopLeScan(mLeScanCallback);
                    isScanning = false;
                    displayView(false);
                    if (deviceFragment == null)
                        showNotFindDevice();
                }
            }, 10000);
            mBluetoothAdapter.startLeScan(mLeScanCallback);
            isScanning = true;
        } else {
            Log.i(TAG, "startScan: false");
            mBluetoothAdapter.stopLeScan(mLeScanCallback);
            mHandler.removeCallbacksAndMessages(null);
            isScanning = false;
        }
    }

    private void showNotFindDevice() {
        if (isDestroyed()) return;
        DeviceNotFindFragment fragment = new DeviceNotFindFragment();
        FragmentTransaction mFragmentTransaction = getSupportFragmentManager().beginTransaction();
        mFragmentTransaction.add(fragment, "deviceNotFind");
        mFragmentTransaction.commitAllowingStateLoss();
    }

    @Override
    public void dataCallback(Map<String, String> maps, SendCmdState sendCmdState) {
        super.dataCallback(maps, sendCmdState);
        switch (sendCmdState) {
            case READ_VERSION:
                String version = maps.get(DeviceKey.KVersion);
                //btUserDeviceversion.setText("V" + version);
                break;
        }
    }


    @Override
    public void onFragmentInteraction() {
        startSerchDevice();
    }
}
